package com.mvvm.library.permission;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.net.Uri;
import android.provider.Settings;
import android.util.Log;

import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;

import com.mvvm.library.app.XMvvm;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;

import java.lang.reflect.Method;

import io.reactivex.functions.Consumer;

/**
 * @创建时间：2023/2/27
 * @作者：小蔡
 * @功能介绍：
 */
@Aspect
public class AndroidPermissionAspect {

    @Pointcut("execution(@com.mvvm.library.permission.AndroidPermission * * (..))")
    public void permission() {

    }

    @SuppressLint("CheckResult")
    @Around("permission()")
    public void handlePermission(ProceedingJoinPoint joinPoint) {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        if (!method.isAnnotationPresent(AndroidPermission.class)) {
            return;
        }
        AndroidPermission permission = method.getAnnotation(AndroidPermission.class);
        String[] permissions = permission.permissions();
        if (permissions.length <= 0) {
            try {
                joinPoint.proceed();
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }
            return;
        }
        Object target = joinPoint.getThis();
        RxPermissions rxPermission;
        if (target instanceof Fragment) {
            Fragment fragment = (Fragment) target;
            rxPermission = new RxPermissions(fragment);
        } else if (target instanceof FragmentActivity) {
            FragmentActivity activity = (FragmentActivity) target;
            rxPermission = new RxPermissions(activity);
        } else {
            try {
                joinPoint.proceed();
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }
            return;
        }
        rxPermission.requestEachCombined(permissions)
                .subscribe(new Consumer< Permission >() {
                    @Override
                    public void accept(Permission permission) throws Exception {
                        Consumer< Permission > onNext = null;
                        Object[] args = joinPoint.getArgs();
                        if (args != null && args.length > 0) {
                            for (Object arg : args) {
                                if (arg instanceof Consumer) {
                                    onNext = (Consumer< Permission >) arg;
                                }
                            }
                        }
                        if (onNext != null) {
                            onNext.accept(permission);
                        } else {
                            if (permission.granted) {
                                // 用户已经同意该权限
                                try {
                                    joinPoint.proceed();
                                } catch (Throwable throwable) {
                                    throwable.printStackTrace();
                                }
                            } else if (permission.shouldShowRequestPermissionRationale) {
                                Log.i("TAG", "拒绝权限: ");
                            } else {
                                Log.i("TAG", "点击不再询问权限: ");
                                if (target instanceof FragmentActivity){
                                    FragmentActivity activity = (FragmentActivity) target;
                                    Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                    Uri uri = Uri.fromParts("package", XMvvm.getInstance().getPackageName(), null);
                                    intent.setData(uri);
                                    activity.startActivityForResult(intent, 0);
                                }
                            }
                        }
                    }
                });
    }
}